Styling and Templating the Property Grid

Built-In Styles

In addition to the default style (grey on white) and the five styles supplied for all WPF Elements controls—Alloy (silver on black), AlloyLight (white on grey), OfficeBlack, OfficeBlue and OfficeSilver—two additional styles are supplied for the PropertyGrid control: Whalesong (light blue) and Radium (bright green). The Whalesong and Radium styles are not available for other WPF Elements controls.

To specify one of the built-in styles, see How Do I Apply a Predefined Style.

You can also create your own styles and templates for the grid.

WPF Elements includes full source for the PropertyGrid control styles, which you can use as a basis for your own styles and templates.
 

Templating Basics

When templating a PropertyGrid control, the following properties are how your template will access the data and logic of the control:

BindingView The set of entries displayed in the grid
EditorSelector Provides the data templates for displaying and editing grid entries

Thus, the part of your template that handles the listing and selection of entries should bind its items source to the BindingView property, and the part of your template that displays property values for editing should bind its template selector to the EditorSelector property.

The Templating sample shows a simple example of this in the OneAtATime.xaml file. In this sample, a ComboBox is used to display and select from the list of properties, and a ContentControl hosts the editor for the selected property.

The samples in the Templating project are simplified to make them easier to understand. The built-in styles are more comprehensive so they’re a better basis for production styles.
 

Template Parts

The PropertyGrid control gives special handling to template elements with the following names if they are present:

PART_Grid If your template contains a Selector element (e.g. a ListBox or TreeView) that displays the PropertyGridRows of the PropertyGrid control, you should give it this name. This will cause the PropertyGrid to detect selection change events on the element and raise the SelectedGridItemChanged event.

Commands

The PropertyGrid control supports the following commands which can be sent from a custom template:

CollectionAddCommand Adds an empty entry to a collection. The CommandParameter is the collection to which to add.
CollectionRemoveCommand Removes the item corresponding to a CollectionElement node from its parent collection. The CommandParameter is the node representing the item.

Styling and Templating the Built-In Editors

If you are substantially retemplating or restyling the PropertyGrid to fit an application visual style, you may also need to change the style of the built-in editors.

To do this, use the PropertyGrid.BuiltInEditorStyles property. For each editor that you need to restyle, create a BuiltInEditorStyle specifying the resource key of that editor and the new visual style. This can be a simple change such as changing the foreground and background colors to be consistent with your application theme, or a complete retemplating.

For examples of restyling built-in editors, see the source code provided for the built-in styles (in the Source directory under the installation folder). See also the Templating sample for other examples. The following code, for example, styles the text editor to use a “white on black” style with rounded corners:

CopyRestyling the built-in text box editor
<ms:BuiltInEditorStyle EditorKey='{x:Static ms:PropertyGrid.SimpleTextEditorKey}'>
              <Style TargetType='{x:Type ms:TextBox}'>
                <Setter Property='Control.Foreground' Value='White'/>
                <Setter Property='Control.Template'>
                  <Setter.Value>
                    <ControlTemplate TargetType='{x:Type ms:TextBox}'>
                      <Border CornerRadius='4' Margin='0' Padding='0.25' Background='#333333'>
                        <DockPanel>
                          <ToggleButton x:Name='ErrorPlaceholder' Style='{StaticResource ErrorPopupTriggerStyle}'/>
                          <Popup PlacementTarget='{Binding ElementName=ErrorPlaceholder}' AllowsTransparency='True' StaysOpen='False' Placement='Bottom' IsOpen='{Binding ElementName=ErrorPlaceholder, Path=IsChecked}'>
                            <ItemsControl ItemTemplate='{StaticResource ValidationErrorMessage}' ItemsSource='{Binding RelativeSource={RelativeSource AncestorType={x:Type ms:TextBox}}, Path=(Validation.Errors)}'/>
                          </Popup>
                          <ScrollViewer x:Name='PART_ContentHost' Margin='1'/>
                        </DockPanel>
                      </Border>
                      <ControlTemplate.Triggers>
                        <Trigger Property='Validation.HasError' Value='True'>
                          <Setter TargetName='ErrorPlaceholder' Property='Visibility' Value='Visible'/>
                        </Trigger>
                      </ControlTemplate.Triggers>
                    </ControlTemplate>
                  </Setter.Value>
                </Setter>
                <Setter Property='Validation.ErrorTemplate'>
                  <Setter.Value>
                    <ControlTemplate>
                      <DockPanel>
                        <Ellipse Margin='0,0,8,0' ToolTip='{Binding ElementName=EditorHolder, Path=AdornedElement.(Validation.Errors)[0].ErrorContent}' Width='6' Height='6' Fill='Red'/>
                        <AdornedElementPlaceholder x:Name='EditorHolder'/>
                      </DockPanel>
                    </ControlTemplate>
                  </Setter.Value>
                </Setter>
              </Style>
            </ms:BuiltInEditorStyle>

Styles declared in a PropertyEditor override styles declared in a BuiltInEditorStyle. If you are restyling a built-in editor, but need to perform additional styling on a per-edited-property basis, take care to use BasedOn to ensure that your baseline customisations are picked up.